package com.tencent.wxcloudrun.controller;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.tencent.wxcloudrun.config.ApiResponse;
import com.tencent.wxcloudrun.controller.form.*;
import com.tencent.wxcloudrun.controller.vo.AdminAuthInfoVo;
import com.tencent.wxcloudrun.dto.PaginationInfo;
import com.tencent.wxcloudrun.model.Admin;
import com.tencent.wxcloudrun.model.ApplyRecord;
import com.tencent.wxcloudrun.model.Task;
import com.tencent.wxcloudrun.service.AdminService;
import com.tencent.wxcloudrun.service.ApplyRecordService;
import com.tencent.wxcloudrun.service.AuthService;
import com.tencent.wxcloudrun.service.TaskService;
import com.tencent.wxcloudrun.utils.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/admin")
public class AdminController {
    private final Logger logger = LoggerFactory.getLogger(AdminController.class);
    private final ApplyRecordService applyRecordService;
    private final AdminService adminService;
    private final TaskService taskService;
    private final AuthService authService;

    private final static String AdminOpCode = "8080";

    private final static Boolean EnterOpCode = true;

    public AdminController(
            ApplyRecordService applyRecordService,
            AdminService adminService,
            TaskService taskService,
            AuthService authService) {
        this.applyRecordService = applyRecordService;
        this.adminService = adminService;
        this.taskService = taskService;
        this.authService = authService;
    }

    // 提取公共的身份验证方法
    private Optional<Admin> authenticateAdmin(@RequestHeader("Authorization") String token) {
        String username = JwtUtil.parseToken(token);
        if (username == null) {
            return Optional.empty();
        }
        return adminService.findByUsername(username);
    }



    /**
     * 用户登录
     */
    @PostMapping("/login")
    public ApiResponse login(@RequestBody AdminLoginRequestForm form) {
        logger.info("管理员登录: {}", form.getUsername());
        try {
            Optional<Admin> adminOpt = adminService.findByUsername(form.getUsername());
            if (!adminOpt.isPresent()) {
                throw new RuntimeException("未找到该帐号");
            }
            Admin admin = adminOpt.get();
            if (!form.getPassword().equals(admin.getPassword())) {
                throw new RuntimeException("密码错误");
            }
            String token = JwtUtil.generateToken(admin.getUsername());
            return ApiResponse.ok(AdminAuthInfoVo.buildByAdmin(admin, token));
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 获取当前用户的账户信息
     */
    @GetMapping("/current/auth")
    public ApiResponse getAuthInfo(@RequestHeader("Authorization") String token) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        return adminOpt.map(admin -> ApiResponse.ok(AdminAuthInfoVo.buildByAdmin(admin, token)))
                .orElseGet(() -> ApiResponse.authError("帐号未登录，请刷新后重试"));
    }


    // 分页查询 + 查询条件（如：状态和手机号）
    @GetMapping("/apply/review/list")
    public ApiResponse getApplyRecords(
            @RequestHeader("Authorization") String token,
            @RequestParam(required = false) ApplyRecord.LoanStatus status,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) String name,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("帐号未登录，请刷新后重试");
        }
        Pageable pageable = PageRequest.of(page, size);
        Page<ApplyRecord> result = applyRecordService.searchApplyRecords(status, phone, name, pageable);
        PaginationInfo<ApplyRecord> paginationInfo = new PaginationInfo<>(
                result.getContent(),
                result.getTotalElements(),
                result.getNumber() + 1,
                result.getSize()
        );
        return ApiResponse.ok(paginationInfo);
    }

    @PostMapping("/check/op/code")
    public ApiResponse checkOpCode(@RequestHeader("Authorization") String token, @RequestBody Map<String, String> params) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("帐号未登录，请刷新后重试");
        }
        String opCode = params.get("opCode");
        if (!AdminOpCode.equals(opCode) && BooleanUtil.isTrue(EnterOpCode)) {
            return ApiResponse.ok("error");
        }
        return ApiResponse.ok("ok");
    }

    @PostMapping("/update/apply/status")
    public ApiResponse modifyApplyRecordStatus(@RequestHeader("Authorization") String token, @Validated @RequestBody UpdateApplyStatusForm form) {
        try {
            Optional<Admin> adminOpt = authenticateAdmin(token);
            if (!adminOpt.isPresent()) {
                return ApiResponse.authError("帐号未登录，请刷新后重试");
            }
            Long recordId = form.getRecordId();
            String status = form.getStatus();
            if (!AdminOpCode.equals(form.getOpCode()) && BooleanUtil.isTrue(EnterOpCode)) {
                return ApiResponse.error("操作密码不正确");
            }
            ApplyRecord applyRecord = applyRecordService.modifyApplyRecordStatus(recordId, ApplyRecord.LoanStatus.valueOf(status));
            if (applyRecord == null) {
                return ApiResponse.error("未找到对应的申请记录");
            }
            if (applyRecord.getStatus() == ApplyRecord.LoanStatus.DISBURSED) {
                try {
                    taskService.generateRepaymentPlan(applyRecord);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                    return ApiResponse.error("生成任务日历失败");
                }
            } else if (applyRecord.getStatus() == ApplyRecord.LoanStatus.CLOSED) {
                taskService.updateTaskStatusByApplyRecordId(applyRecord.getId(), Task.TaskStatus.CLOSE);
            }
            return ApiResponse.ok(applyRecord);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }

    @PostMapping("/update/apply/week")
    public ApiResponse modifyApplyRecordWeekNum(@RequestHeader("Authorization") String token, @RequestBody Map<String, String> params) {
        try {
            Optional<Admin> adminOpt = authenticateAdmin(token);
            if (!adminOpt.isPresent()) {
                return ApiResponse.authError("帐号未登录，请刷新后重试");
            }
            String recordId = params.get("recordId");
            String weekNum = params.get("weekNum");
            String opCode = params.get("opCode");
            if (!AdminOpCode.equals(opCode) && BooleanUtil.isTrue(EnterOpCode)) {
                return ApiResponse.error("操作密码不正确");
            }
            if (StrUtil.isBlank(weekNum) || StrUtil.isBlank(recordId)) {
                return ApiResponse.error("参数异常");
            }
            ApplyRecord applyRecord = applyRecordService.modifyApplyRecordWeekNum(Long.parseLong(recordId), Integer.valueOf(weekNum));
            if (applyRecord != null) {
                return ApiResponse.ok(applyRecord);
            } else {
                return ApiResponse.error("未找到对应的申请记录");
            }
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }

    @PostMapping("/update/apply/product")
    public ApiResponse modifyApplyRecordProduct(@RequestHeader("Authorization") String token, @RequestBody Map<String, String> params) {
        try {
            Optional<Admin> adminOpt = authenticateAdmin(token);
            if (!adminOpt.isPresent()) {
                return ApiResponse.authError("帐号未登录，请刷新后重试");
            }
            String recordId = params.get("recordId");
            String limitAmount = params.get("limitAmount");
            String opCode = params.get("opCode");
            if (!AdminOpCode.equals(opCode) && BooleanUtil.isTrue(EnterOpCode)) {
                return ApiResponse.error("操作密码不正确");
            }
            if (StrUtil.isBlank(limitAmount) || StrUtil.isBlank(recordId)) {
                return ApiResponse.error("参数异常");
            }
            ApplyRecord applyRecord = applyRecordService.modifyApplyRecordProduct(Long.parseLong(recordId), Integer.valueOf(limitAmount));
            if (applyRecord != null) {
                return ApiResponse.ok(applyRecord);
            } else {
                return ApiResponse.error("未找到对应的申请记录");
            }
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }

    @PostMapping("/update/apply/remark")
    public ApiResponse modifyApplyRecordRemark(@RequestHeader("Authorization") String token, @RequestBody Map<String, String> params) {
        try {
            Optional<Admin> adminOpt = authenticateAdmin(token);
            if (!adminOpt.isPresent()) {
                return ApiResponse.authError("帐号未登录，请刷新后重试");
            }
            String recordId = params.get("recordId");
            String remark = params.get("remark");
            String opCode = params.get("opCode");
            if (!AdminOpCode.equals(opCode) && BooleanUtil.isTrue(EnterOpCode)) {
                return ApiResponse.error("操作密码不正确");
            }
            ApplyRecord applyRecord = applyRecordService.modifyApplyRecordRemark(Long.parseLong(recordId), remark);
            if (applyRecord != null) {
                return ApiResponse.ok(applyRecord);
            } else {
                return ApiResponse.error("未找到对应的申请记录");
            }
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }

    // 根据任务ID修改任务状态
    @PostMapping("/update/task/status")
    public ApiResponse updateTaskStatus(@RequestHeader("Authorization") String token, @RequestBody TaskStatusUpdateForm form) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("帐号未登录，请刷新后重试");
        }
        if (!AdminOpCode.equals(form.getOpCode()) && BooleanUtil.isTrue(EnterOpCode)) {
            return ApiResponse.error("操作密码不正确");
        }
        try {
            taskService.updateTaskStatus(form.getTaskId(), form.getStatus(), form.getActualRepaymentDate(), form.getOverdueAmount());
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
        return ApiResponse.ok("任务状态更新成功");
    }

    @GetMapping("/task/review/list")
    public ApiResponse getTaskList(
            @RequestHeader("Authorization") String token,
            @RequestParam(required = false) Task.TaskStatus status,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate dateTime,
            @RequestParam(required = false) String name,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("帐号未登录，请刷新后重试");
        }
        Pageable pageable = PageRequest.of(page, size);
        Page<Task> result = taskService.searchTaskRecords(null, status, phone, name, dateTime, pageable);
        PaginationInfo<Task> paginationInfo = new PaginationInfo<>(
                result.getContent(),
                result.getTotalElements(),
                result.getNumber() + 1,
                result.getSize()
        );
        return ApiResponse.ok(paginationInfo);
    }

    @GetMapping("/today/task/review/list")
    public ApiResponse getTaskListByEndDay(
            @RequestHeader("Authorization") String token,
            @RequestParam(required = false) Task.TaskStatus status,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate dateTime,
            @RequestParam(required = false) String name,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("帐号未登录，请刷新后重试");
        }
        Pageable pageable = PageRequest.of(page, size);
        Page<Task> result = taskService.searchTaskRecordsByEndDate(null, status, phone, name, dateTime, pageable);
        PaginationInfo<Task> paginationInfo = new PaginationInfo<>(
                result.getContent(),
                result.getTotalElements(),
                result.getNumber() + 1,
                result.getSize()
        );
        return ApiResponse.ok(paginationInfo);
    }


    @GetMapping("/overdue/task/review/list")
    public ApiResponse getOverdueTaskList(
            @RequestHeader("Authorization") String token,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) String name,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("帐号未登录，请刷新后重试");
        }
        Pageable pageable = PageRequest.of(page, size);
        Page<Task> result = taskService.searchOverdueTaskRecords(null, phone, name, pageable);
        PaginationInfo<Task> paginationInfo = new PaginationInfo<>(
                result.getContent(),
                result.getTotalElements(),
                result.getNumber() + 1,
                result.getSize()
        );
        return ApiResponse.ok(paginationInfo);
    }

    /**
     * 重置密码
     */
    @PostMapping("/reset/password")
    public ApiResponse resetPassword(@RequestHeader("Authorization") String token, @Validated @RequestBody ResetPasswordRequestForm form) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("帐号未登录，请刷新后重试");
        }
        if (!AdminOpCode.equals(form.getOpCode()) && BooleanUtil.isTrue(EnterOpCode)) {
            return ApiResponse.error("操作密码不正确");
        }
        try {
            authService.resetPassword(form.getMobile(), form.getNewPwd());
            return ApiResponse.ok("ok");
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 删除申请
     */
    @DeleteMapping("/delete/apply/{id}/{opCode}")
    public ApiResponse deleteApplyRecord(@RequestHeader("Authorization") String token, @PathVariable Long id, @PathVariable String opCode) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("用户未登录，请重新登录");
        }
        if (!AdminOpCode.equals(opCode) && BooleanUtil.isTrue(EnterOpCode)) {
            return ApiResponse.error("操作密码不正确");
        }
        applyRecordService.deleteById(id);
        return ApiResponse.ok("删除成功");
    }

    /**
     * 删除任务
     */
    @DeleteMapping("/delete/task/{id}/{opCode}")
    public ApiResponse deleteApplyTask(@RequestHeader("Authorization") String token, @PathVariable Long id, @PathVariable String opCode) {
        Optional<Admin> adminOpt = authenticateAdmin(token);
        if (!adminOpt.isPresent()) {
            return ApiResponse.authError("用户未登录，请重新登录");
        }
        if (!AdminOpCode.equals(opCode) && BooleanUtil.isTrue(EnterOpCode)) {
            return ApiResponse.error("操作密码不正确");
        }
        // 原代码这里调用的是 applyRecordService，推测应该是 taskService
        taskService.deleteById(id);
        return ApiResponse.ok("删除成功");
    }
}